package com.surrealbananapeel.battleship;

/**
 * This is a class for holding a points coordinates in 3D as well as the 
 * state of the point and the number of times the point has been used.
 * 
 * @author Emmett Little and Alberto Saavedra
 */
public class Point
{
    public static enum State
    {
        EMPTY, MISS, HIT, DETECTED
    };
    
    private int x;
    private int y;
    private int z;
    private State state;
    private int timesUsed;
    
    /**
     * Create a new point with coordinates and a state.
     * 
     * @param x The x coordinate
     * @param y The y coordinate
     * @param z The z coordinate
     * @param state
     */
    public Point(int x, int y, int z, State state)
    {
        this.x = x;
        this.y = y;
        this.z = z;
        timesUsed = 0;
        this.setState(state);
    }
    
    /**
     * Create a new point object with just coordinates.
     * 
     * @param x The x coordinate.
     * @param y The y coordinate.
     * @param z The z coordinate.
     */
    public Point(int x, int y, int z)
    {
        this(x, y, z, State.EMPTY);
    }
    
    /**
     * Create a new point based off the supplied string, which is a comma 
     * seperated value of x, y, and z.
     * 
     * @param point The string to make the point with.
     */
    public Point(String point)
    {
        String[] points = point.split(",");
        this.x = Integer.parseInt(points[0]);
        this.y = Integer.parseInt(points[1]);
        this.z = Integer.parseInt(points[2]);
    }
    
    /**
     * Swaps the two selected parameters.
     * 
     * @param x If x is to be swapped
     * @param y If y is to be swapped
     * @param z If z is to be swapped
     */
    public void swap(boolean x, boolean y, boolean z)
    {
        int temp;
        if (x && y)
        {
            temp = this.x;
            this.x = this.y;
            this.y = temp;
        }
        else if (x && z)
        {
            temp = this.x;
            this.x = this.z;
            this.z = temp;
        }
        else if (y && z)
        {
            temp = this.y;
            this.y = this.z;
            this.z = temp;
        }
    }
    
    /**
     * Get the x coordinate.
     * 
     * @return The X
     */
    public int getX()
    {
        return x;
    }
    
    /**
     * Set the x coordinate.
     * 
     * @param x The value to set x to
     */
    public void setX(int x)
    {
        this.x = x;
    }
    
    /**
     * Get the y coordinate.
     * 
     * @return The y
     */
    public int getY()
    {
        return y;
    }
    
    /**
     * Set the y coordinate.
     * 
     * @param y The value to set y to
     */
    public void setY(int y)
    {
        this.y = y;
    }
    
    /**
     * Get the x coordinate.
     * 
     * @return The z
     */
    public int getZ()
    {
        return z;
    }
    
    /**
     * Set the z coordinate.
     * 
     * @param z The value to set x to
     */
    public void setZ(int z)
    {
        this.z = z;
    }
    
    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString()
    {
        return x + "," + y + "," + z;
    }
    
    /* (non-Javadoc)
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object o)
    {
        if (!(o instanceof Point))
            return false;
        
        Point p = (Point) o;
        return (p.x == x && p.y == y && p.z == z) ? true : false;
    }
    
    /**
     * Add the supplied value to the x coordinate.
     * 
     * @param x The value to add to x
     */
    public void addX(int x)
    {
        this.x += x;
    }
    
    /**
     * Add the supplied value to the y coordinate.
     * 
     * @param y The value to add to y
     */
    public void addY(int y)
    {
        this.y += y;
    }
    
    /**
     * Add the supplied value to the z coordinate.
     * 
     * @param z The value to add to z
     */
    public void addZ(int z)
    {
        this.z += z;
    }
    
    /**
     * Set the state to the supplied value.
     * 
     * @param state The new state
     */
    public void setState(State state)
    {
        this.state = state;
    }
    
    /**
     * Get the current state.
     * 
     * @return The state of the point
     */
    public State getState()
    {
        return state;
    }
    
    /**
     * Get the times the point has been used.
     * 
     * @return Total times the point has been used
     */
    public int getTimesUsed()
    {
        return timesUsed;
    }
    
    /**
     * Set the times used.
     * 
     * @param timesUsed The times the points has been used
     */
    public void setTimesUsed(int timesUsed)
    {
        this.timesUsed = timesUsed;
    }
    
    /**
     * Increment the times the point has been used.
     */
    public void incrementTimesUsed()
    {
        timesUsed++;
    }
}
